package com.kun.video.thread;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义线程工厂，支持线程命名、优先级和守护线程配置
 * 特性：
 * 1. 自动生成递增的线程名称（如prefix-thread-1）
 * 2. 可配置线程优先级和守护线程状态
 * 3. 全局未捕获异常处理
 *
 * @author gzc
 * @since 2025/2/7
 **/
public class NamedThreadFactory implements ThreadFactory {
    private final Logger log = LoggerFactory.getLogger(NamedThreadFactory.class);

    /**
     * 线程编号生成器
     */
    protected final AtomicInteger THREAD_NUM = new AtomicInteger(1);

    /**
     * 线程名称前缀（格式：prefix-thread-）
     */
    protected final String THREAD_NAME_PREFIX;

    /**
     * 是否创建守护线程
     */
    protected final boolean ENABLE_DAEMON;

    /**
     * 线程优先级（默认Thread.NORM_PRIORITY=5）
     */
    protected final int PRIORITY;

    /**
     * 所属线程组（默认继承当前线程组）
     */
    protected final ThreadGroup THREAD_GROUP;

    //------------------------- 构造函数 -------------------------

    /**
     * 默认构造函数（线程名前缀为"name-thread-"）
     */
    public NamedThreadFactory() {
        this("name");
    }

    /**
     * 指定线程名前缀的构造函数
     *
     * @param prefix 名称前缀（如"io"会生成"io-thread-1"）
     */
    public NamedThreadFactory(String prefix) {
        this(prefix, Thread.NORM_PRIORITY, false);
    }

    /**
     * 全参数构造函数
     *
     * @param prefix   线程名前缀
     * @param priority 线程优先级（1-10）
     * @param daemon   是否守护线程
     */
    public NamedThreadFactory(String prefix, int priority, boolean daemon) {
        THREAD_NAME_PREFIX = prefix + "-thread-";
        PRIORITY = validatePriority(priority);
        ENABLE_DAEMON = daemon;
        THREAD_GROUP = Thread.currentThread().getThreadGroup();
    }

    //------------------------- 核心方法 -------------------------

    /**
     * 创建新线程（自动配置名称、优先级和异常处理）
     *
     * @param runnable 待执行任务（需非空）
     * @return 配置完成的线程实例
     */
    @Override
    public Thread newThread(@NotNull Runnable runnable) {
        String name = THREAD_NAME_PREFIX + THREAD_NUM.getAndIncrement();
        Thread thread = new Thread(THREAD_GROUP, runnable, name, 0);
        thread.setDaemon(ENABLE_DAEMON);
        thread.setPriority(PRIORITY);
        // 全局异常处理器（防止线程静默崩溃）
        thread.setUncaughtExceptionHandler((t, ex) ->
                log.error("线程[{}]发生未捕获异常: {}", t.getName(), ex.getMessage(), ex)
        );
        return thread;
    }

    //------------------------- 工具方法 -------------------------

    /**
     * 验证优先级范围（1-10），超出则返回默认值5
     */
    private int validatePriority(int priority) {
        return (priority >= Thread.MIN_PRIORITY && priority <= Thread.MAX_PRIORITY) ?
                priority : Thread.NORM_PRIORITY;
    }

    /**
     * 获取线程组信息
     */
    public ThreadGroup getThreadGroup() {
        return THREAD_GROUP;
    }

    /**
     * 获取配置的线程优先级
     */
    public int getPriority() {
        return PRIORITY;
    }
}